package cn.xd.base.persistence.repository.impl;

import cn.hutool.core.util.StrUtil;
import cn.xd.base.basic.type.DictCode;
import cn.xd.base.basic.type.DictId;
import cn.xd.base.domain.entity.Dict;
import cn.xd.base.domain.entity.KeyValue;
import cn.xd.base.domain.repository.DictRepository;
import cn.xd.base.domain.repository.KeyValueRepository;
import cn.xd.base.persistence.dos.DictConverter;
import cn.xd.base.persistence.dos.DictDO;
import cn.xd.base.persistence.dos.KeyValueConverter;
import cn.xd.base.persistence.dos.KeyValueDO;
import cn.xd.base.persistence.mps.DictMpService;
import cn.xd.base.persistence.mps.KeyValueMpService;
import cn.xd.core.ddd.db.DbRepositorySupport;
import cn.xd.core.ddd.diff.Diff;
import cn.xd.core.ddd.diff.EntityDiff;
import cn.xd.core.response.ObjectResult;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Repository;

import java.util.Collection;

/**
 * @author : mirzaLin
 * @data : 2023/11/20
 * @description :
 **/
@Repository
public class DictRepositoryImpl extends DbRepositorySupport<Dict, DictId> implements DictRepository {
    @Resource
    private DictMpService dictMpService;
    @Resource
    private KeyValueMpService keyValueMpService;
    @Resource
    private KeyValueRepository keyValueRepository;

    @Override
    protected void onInsert(Dict aggregate) {
        find(aggregate.getCode()).isNotEmptyThrow("存在重名的字典编码");
        dictMpService.saveResult(aggregate, DictConverter.INSTANCE);
    }

    @Override
    protected Dict onSelect(DictId dictId) {
        return dictMpService.getResult(dictId, DictConverter.INSTANCE).get();
    }

    @Override
    protected void onUpdate(Dict aggregate, EntityDiff diff) {
        if (diff.isSelfModified()) {
            DictDO bean = diff.getBean(DictDO.class);
            if (StrUtil.isNotBlank(bean.getCode())) {
                Diff code = (Diff) diff.getDiff("code");
                String oldCode = (String) code.getOldValue();
                find(DictCode.of(bean.getCode())).isNotEmptyThrow("存在重名的字典编码");
                KeyValueDO updateKeyValue = KeyValueConverter.INSTANCE.toData(KeyValue.updateKeyValue(bean.getCode()));
                keyValueMpService.update(updateKeyValue, new UpdateWrapper<KeyValueDO>().lambda().eq(KeyValueDO::getDictCode, oldCode));
            }

            if (StrUtil.isNotBlank(bean.getDictKeyType())) {
                Collection<KeyValue> keyValues = keyValueRepository.getKeyValueByType(aggregate.getCode()).get();
                for (KeyValue keyValue : keyValues) {
                    aggregate.check(keyValue.getDictKey().getValue());
                }
            }
            dictMpService.updateResult(bean);
        }

    }

    @Override
    protected void onDelete(Dict aggregate) {
        keyValueMpService.remove(new LambdaQueryWrapper<KeyValueDO>().eq(KeyValueDO::getDictCode, aggregate.getCode().getValue()));
        dictMpService.removeById(aggregate.getId().getValue());
    }

    /**
     * 通过字典编码查找一条记录
     *
     * @param code 字典编码
     * @return 字典
     */
    @Override
    public ObjectResult<Dict> find(DictCode code) {
        LambdaQueryWrapper<DictDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StrUtil.isNotBlank(code.getValue()), DictDO::getCode, code.getValue());
        Dict dict = dictMpService.getOneForLimitOneResult(wrapper, DictConverter.INSTANCE).isNotEmpty(this::attach);
        return ObjectResult.of(dict);
    }
}
